package com.gaofeng.customviewdemo

import android.annotation.SuppressLint
import android.animation.ObjectAnimator
import android.content.Context
import com.gaofeng.customviewdemo.CircleButton
import android.widget.ImageView.ScaleType
import android.util.TypedValue
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import com.gaofeng.customviewdemo.R
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.widget.ImageView

@SuppressLint("AppCompatCustomView")
class CircleButton : ImageView {
    private var centerY = 0
    private var centerX = 0
    private var outerRadius = 0
    private var pressedRingRadius = 0
    private var circlePaint: Paint? = null
    private var focusPaint: Paint? = null
    private var animationProgress = 0f
    private var pressedRingWidth = 0
    private var defaultColor = Color.BLACK
    private var pressedColor = 0
    private var pressedAnimator: ObjectAnimator? = null

    constructor(context: Context) : super(context) {
        init(context, null)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init(context, attrs)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
        context,
        attrs,
        defStyle
    ) {
        init(context, attrs)
    }

    override fun setPressed(pressed: Boolean) {
        super.setPressed(pressed)
        if (circlePaint != null) {
            circlePaint!!.color = if (pressed) pressedColor else defaultColor
        }
        if (pressed) {
            Log.d(TAG, "setPressed: " + true)
            showPressedRing()
        } else {
            Log.d(TAG, "setPressed: " + false)
            hidePressedRing()
        }
    }

    override fun onDraw(canvas: Canvas) {
        canvas.drawCircle(
            centerX.toFloat(),
            centerY.toFloat(),
            pressedRingRadius + animationProgress,
            focusPaint!!
        )
        canvas.drawCircle(
            centerX.toFloat(),
            centerY.toFloat(),
            (outerRadius - pressedRingWidth).toFloat(),
            circlePaint!!
        )
        super.onDraw(canvas)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        centerX = w / 2
        centerY = h / 2
        outerRadius = Math.min(w, h) / 2
        pressedRingRadius = outerRadius - pressedRingWidth - pressedRingWidth / 2
    }

    fun getAnimationProgress(): Float {
        return animationProgress
    }

    fun setAnimationProgress(animationProgress: Float) {
        this.animationProgress = animationProgress
        this.invalidate()
    }

    fun setColor(color: Int) {
        defaultColor = color
        pressedColor = getHighlightColor(color, PRESSED_COLOR_LIGHTUP)
        circlePaint!!.color = defaultColor
        focusPaint!!.color = defaultColor
        focusPaint!!.alpha = PRESSED_RING_ALPHA
        this.invalidate()
    }

    private fun hidePressedRing() {
        pressedAnimator!!.setFloatValues(pressedRingWidth.toFloat(), 0f)
        pressedAnimator!!.start()
    }

    private fun showPressedRing() {
        pressedAnimator!!.setFloatValues(animationProgress, pressedRingWidth.toFloat())
        pressedAnimator!!.start()
    }

    private fun init(context: Context, attrs: AttributeSet?) {
        this.isFocusable = true
        this.scaleType = ScaleType.CENTER_INSIDE
        isClickable = true
        circlePaint = Paint(Paint.ANTI_ALIAS_FLAG)
        circlePaint!!.style = Paint.Style.FILL
        focusPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        focusPaint!!.style = Paint.Style.STROKE
        pressedRingWidth = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            DEFAULT_PRESSED_RING_WIDTH_DIP.toFloat(),
            resources
                .displayMetrics
        ).toInt()
        var color = Color.BLACK
        if (attrs != null) {
            val a = context.obtainStyledAttributes(attrs, R.styleable.CircleButton)
            color = a.getColor(R.styleable.CircleButton_cb_color, color)
            pressedRingWidth = a.getDimension(
                R.styleable.CircleButton_cb_pressedRingWidth,
                pressedRingWidth.toFloat()
            )
                .toInt()
            a.recycle()
        }
        setColor(color)
        focusPaint!!.strokeWidth = pressedRingWidth.toFloat()
        val pressedAnimationTime = resources.getInteger(ANIMATION_TIME_ID)
        pressedAnimator = ObjectAnimator.ofFloat(this, "animationProgress", 0f, 0f)
        pressedAnimator?.setDuration(pressedAnimationTime.toLong())
    }

    private fun getHighlightColor(color: Int, amount: Int): Int {
        return Color.argb(
            Math.min(255, Color.alpha(color)), Math.min(255, Color.red(color) + amount),
            Math.min(255, Color.green(color) + amount), Math.min(255, Color.blue(color) + amount)
        )
    }

    companion object {
        private const val TAG = "CircleButton"
        private const val PRESSED_COLOR_LIGHTUP = 255 / 25
        private const val PRESSED_RING_ALPHA = 75
        private const val DEFAULT_PRESSED_RING_WIDTH_DIP = 4
        private const val ANIMATION_TIME_ID = android.R.integer.config_shortAnimTime
    }
}